#include <iostream>
#include <unistd.h>
#include <signal.h>

// 以下实验测试1~31的信号

// sigaction
// 实验证明pending 在执行handler 之前就被置为0了
// 也就是在handler中我们打印pending 未决位图全0
// 这也符合 “未决” 一次的含义。所以在我处理期间要是再
// 收到同样的信号 操作系统就知道了，会继续handler
// 但是没必要记录多个同样的信号。


void PrintBlock()
{
    sigset_t block;
    sigemptyset(&block);
    sigprocmask(SIG_SETMASK, nullptr, &block);
    std::cout << "block:";
    for (int i = 31; i > 0; --i)
    {
        std::cout << (sigismember(&block, i) ? 1 : 0);
    }
    std::cout << std::endl;
}

void PrintPending()
{
    sigset_t pending;
    sigpending(&pending);
    
    std::cout << "pending:";
    for (int i = 31; i > 0; --i)
    {
        std::cout << sigismember(&pending, i) ? 1 : 0;
    }
    std::cout << std::endl;
}

void Print(sigset_t* set)
{
    for (int i = 31; i > 0; --i)
    {
        std::cout << sigismember(set, i) ? 1 : 0;
    }
    std::cout << std::endl;
}

void handler(int signo)
{
    static int cnt = 0;
    cnt++;
    while (true)
    {
        ::std::cout << "get a signal: " << signo << " pid: " << ::getpid() << " cnt: " << cnt << std::endl;
        // PrintBlock();
        PrintPending();
        sleep(1);
        break;
    }
    // exit(1);
}

int main()
{

    struct sigaction sa, o_sa;

    sa.sa_handler = handler;

    // 增加顺带阻塞的信号
    // 也就是屏蔽的信号
    sigset_t* p_mask = &sa.sa_mask;
    sigemptyset(p_mask);
    sigaddset(p_mask, 4);
    sigaddset(p_mask, 5);
    sigaddset(p_mask, 6);
    // sigaddset(&mask, 9);

    ::sigaction(SIGINT, &sa, &o_sa);
    Print(p_mask);
    while (true)
    {
        // PrintBlock();
        PrintPending();
        pause();
    }

    return 0;
}

// // 信号 block pending handler
// void PrintPending(const sigset_t &sigset)
// {

//     std::cout << "pending table [" << getpid() << "]:";
//     int signo = 31;
//     for (signo = 31; signo > 0; --signo)
//     {
//         // sigismember(&sigset, signo) ? putchar('1') : putchar('0');
//         sigismember(&sigset, signo) ? (std::cout << 1) : (std::cout << 0);
//     }
//     std::cout << std::endl;
// }

// int main()
// {
//     signal(2,SIG_IGN);
//     // 栈上开辟两个信号表
//     sigset_t block, old_block;
//     // 栈上开辟的空间是乱码 做清零
//     sigemptyset(&block);
//     sigemptyset(&old_block);

//     // 2号信号设置进入用户定义的表
//     sigaddset(&block, 2);
//     // 设置进进程PCB中（内核中）
//     sigprocmask(SIG_SETMASK, &block, &old_block);

//     int cnt = 0;
//     while (true)
//     {
//         // 获取 pending表 未决表
//         sigset_t pending;
//         sigpending(&pending);

//         PrintPending(pending);
//         sleep(1);
//         ++cnt;
//         if(cnt == 10){
//             std::cout << "解除对2号信号的屏蔽" << std::endl;
//             sigprocmask(SIG_SETMASK, &old_block, nullptr);
//         }

//     }

//     return 0;
// }

// void Handler(int signo){

//     std::cout << "signo: " << signo << std::endl;

// }
// // 9号信号无法被捕捉

// int main(){

//     // signal(SIGINT, Handler);
//     // 杀不死进程？？？？？？不行
//     for(int signo = 0; signo < 32; ++signo){
//         signal(signo, Handler);
//     }

//     while(true){
//         std::cout << "while phrase" << std::endl;
//         sleep(1);
//     }
//     return 0;
// }